import hudson.model.*;
import com.fasterxml.jackson.databind.ObjectMapper

pipeline {
    agent any
    // 环境变量
    environment {
        successInfo = null
        failInfo = null
    }
    // 入参定义
    parameters {
        string(name: 'hospitalList', defaultValue: '', description: '机构列表JSON字符串')
        string(name: 'service_name', defaultValue: 'service01_app', description: '服务名')
        string(name: 'projectName', defaultValue: 'tz-hospital-ssm-server', description: '项目名称')
        string(name: 'user_email', defaultValue: '125139887@qq.com', description: '邮件通知')
    }
    stages {
        stage('执行远程命令') {
            steps {
                script {
                    // 错误列表
                    List successList = new ArrayList();
                    // 错误列表
                    List failList = new ArrayList();
                    //获取发布机构列表
                    def slurped = new groovy.json.JsonSlurperClassic().parseText(params.hospitalList)
                    for (info in slurped) {
                        def orgMsg = "=======" + info.orgName + "======" + info.ipAddr + "======"
                        println("执行开始" + orgMsg)
                        try {
                            def sshServer = getServer(info.ipAddr.toString(), info.sshPort, info.orgCode)
                            // 回滚
                            sshCommand remote: sshServer, command: "docker service rollback ${params.service_name}"
                            // 获取镜像版本号
                            def currentImage = sshCommand remote: sshServer, command: "docker service ls --format 'table {{.Image}}' | grep ${params.projectName}"
                            successList.add(new IpAddrInfo(orgCode: info.orgCode, orgName: info.orgName, ipAddr: info.ipAddr, msg: "回滚成功", currentImage: currentImage))
                            sh "echo 执行成功${orgMsg}"
                        } catch (ex) {
                            println(ex)
                            //记录错误信息
                            failList.add(new IpAddrInfo(orgCode: info.orgCode, orgName: info.orgName, ipAddr: info.ipAddr, msg: ex.message))
                        }
                        finally {
                            //记录成功和失败信息到环境变量
                            ObjectMapper successObj = new ObjectMapper()
                            successInfo = successObj.writeValueAsString(successList)
                            ObjectMapper failObj = new ObjectMapper()
                            failInfo = failObj.writeValueAsString(failList)
                        }
                    }
                }
            }
        }
        stage('执行成功打印') {
            steps {
                script {
                    println(successInfo)
                }
            }
        }
        stage('执行失败打印') {
            steps {
                script {
                    println(failInfo)
                }
            }
        }
    }
    post('发送通知') {
        success {
            emailext(
                    subject: "【SUCCESS】## 项目回滚通知 ## $env.JOB_NAME - rollback # $env.BUILD_NUMBER",
                    body: """
~
回滚成功列表
========================
${successInfo}
========================

回滚失败列表
========================
${failInfo}
========================
                    """,
                    to: "${params.user_email}"
            )
        }
        failure {
            emailext(
                    subject: "【FAIL】## 项目回滚通知 ##$env.JOB_NAME - rollback # $env.BUILD_NUMBER",
                    body: """
~
回滚成功列表
========================
${successInfo}
========================

回滚失败列表
========================
${failInfo}
========================
                    """,
                    to: "${params.user_email}"
            )
        }
    }
}

class IpAddrInfo {
    String orgCode
    String orgName
    String ipAddr
    String msg
    String currentImage
}

def getServer(ip, port, orgCode) {
    def remote = [:]
    remote.name = "server-${ip}"
    remote.host = ip
    remote.port = port
    remote.allowAnyHosts = true
    withCredentials([usernamePassword(credentialsId: orgCode, passwordVariable: 'password', usernameVariable: 'userName')]) {
        remote.user = "${userName}"
        remote.password = "${password}"
    }
    return remote
}

